
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import styled from 'styled-components'
import Controller from '../../component/Controller'
import Content from './Content';
import { home, inviteReward, reward } from '../../service';
import { RootState } from '../../store';
import Message from '../../component/Message';
import { HomeResponse, RewardType, Reword } from '../../service/interface';
import Channel from './Channel';
import Space from '../../component/Space';
import Header from '../../component/Header';
import Sheet from '../../component/sheet';
import Icon from '../../component/Icon';
import { handleCoinTimerData } from '../../utils/dataHandle';
import { SECOND_MILL } from '../../constants';
import IconBg from '../../asserts/home_bg.png'
import gtag from '../../google/analytics';
import { GtagEvent } from '../../google/analytics/Event';
import { isIOS } from '../../utils/check';
import Loading from '../../component/Loading';
import NotificationCenter from '../../utils/notification';
import { NotificationPrizeName } from './constants';
import { IconType } from '../../component/sheet/Modal';
import Telegram from '../../utils/telegram';

const Container = styled(Controller)`
    background-color: ${(prop) => prop.theme.background.normal};
`

const Center = styled.div``

const Bottom = styled.div`
    padding: 0 1rem 2.25rem;
    box-sizing: border-box;
    border-radius: .625rem;
    position: relative;
`

const SheetTitle = styled.div`
    width: 100%;
    padding: 0 1.25rem;
    text-align: center;
    box-sizing: border-box;
`

const Dot = styled.div`
    background-color: #FF5867;
    width: .625rem;
    height: .625rem;
    border-radius: 50%;
    font-size: .4375rem;
    color: #fff;
    font-weight: bold;
    display: flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    right: 0;
    top: 0;
    transform: translate(50%, 0);
`

const Gift = styled.div`
    z-index: 1;
    position: absolute;
    left: 1rem;
    top: -1rem;
    transform: translateY(-100%);
`

enum SheetContentNone {
    None = ''
}

const SheetContentType = { ...RewardType, ...SheetContentNone }
type ValueTypes = typeof SheetContentType[keyof typeof SheetContentType];
type SheetContent = {
    title: string
    text: string
    balance: string
    button: string
    type: ValueTypes
    extra?: [IconType]
}

const Home: React.FC = () => {
    return <Container
        hiddenSafeBottom={true}
        imagebackground={{
            image: IconBg,
            style: isIOS() ? {} : { position: 'fixed' } // TODO: why absolute will case some gesture problem in andriod
        }}
    >
        <Main />
    </Container>
}

const Main: React.FC = () => {
    const { t } = useTranslation();
    const user = useSelector((state: RootState) => state.user)

    const [loading, setLoading] = useState(false)
    const [data, setData] = useState<HomeResponse>()
    const [isStart, setIsStart] = useState(false);
    const [btcCount, setBtcCount] = useState(0)
    const [leftCycleCount, setLeftCycleCount] = useState(0)
    const [dynamicInterval, setDynamicInterval] = useState<any[]>([])
    const [refreshFlag, setRefreshFlag] = useState(0)
    const [stopTime, setStopTime] = useState(0)
    const [showSheet, setShowSheet] = useState(false);
    const [sheetContent, setSheetContent] = useState<SheetContent>({ title: '', text: '', balance: '', button: '', type: SheetContentType.None });
    const [rewardInfo, setReward] = useState<Reword>();
    const giftDot = useMemo(() => Number(rewardInfo?.inviteRankReward || 0) || Number(rewardInfo?.inviteReward || 0) || Number(rewardInfo?.inviteRewardTon), [rewardInfo])
    const showGiftDot = useMemo(() => giftDot > 0, [giftDot])
    const sheetIcons: Array<IconType> = useMemo(() => {
        const res: Array<IconType> = [{ icon: true, count: sheetContent.balance }]
        if (sheetContent.extra) {
            res.push(...sheetContent.extra)
        }
        return res
    }, [sheetContent])

    const refresh = useCallback(() => {
        setRefreshFlag(pre => pre + 1)
    }, [setRefreshFlag])

    useEffect(() => {
        NotificationCenter.observer(NotificationPrizeName, () => {
            refresh()
        })
        return () => {
            NotificationCenter.removeObserver(NotificationPrizeName)
        }
    }, [refresh])

    useEffect(() => {
        const callback = (value: any) => {
            const target = value.target;
            if (!target) {
                return
            }
            const isHidden = target.hidden;
            if (!isHidden) {
                refresh();
            }
        }
        window.addEventListener('visibilitychange', callback)
        return () => {
            window.removeEventListener('visibilitychange', callback)
        }
    }, [refresh])

    useEffect(() => {
        const checkReward = async () => {
            const check = await inviteReward();
            if (!check.success) {
                return;
            }

            if (Number(check.data?.beInviteReward || 0) > 0) {
                setShowSheet(true);
                setSheetContent({
                    title: t('modal.invite.person_invte', { person: check.data?.parentName }),
                    balance: check.data?.beInviteReward || '',
                    button: t('modal.invite.get'),
                    type: SheetContentType.BeInvite,
                    text: '',
                    extra: undefined
                })
            }

            setReward(check.data)
        }

        const fetchData = async () => {
            setLoading(true)
            const { success, message, data: info } = await home()
            setLoading(false)
            if (!success) {
                Message.error(message);
                return
            }

            if (!info) {
                return;
            }

            const d = handleCoinTimerData(info);
            setData(info)
            setIsStart(d.start);
            setStopTime(d.stopTime);
            setLeftCycleCount(d.cycle.real);
            setBtcCount(d.balance)

            if (d.cycle.additionTime > 0) {
                setDynamicInterval([{
                    interval: d.cycle.additionTime * SECOND_MILL,
                    count: info?.detector.realDetPower || 0
                }])
            }

        }
        fetchData()
        checkReward()
    }, [user, refreshFlag, t, refresh])

    const onSheetConfirmClick = async () => {
        if (sheetContent.type === SheetContentType.None) {
            setShowSheet(false)
            user.inviteUrl && Telegram.invite(user.inviteUrl)
            return;
        }

        const res = await reward({ type: sheetContent.type })
        if (res.success) {
            refresh();
            setShowSheet(false)
            return;
        }

        Message.error(res.message)
    }

    const onGiftClick = useCallback((info: Reword | undefined) => {
        const inviteReward = Number(info?.inviteReward || 0);
        const inviteRewardTon = Number(info?.inviteRewardTon || 0);
        const reward = Number(info?.inviteRankReward || 0);
        gtag.event(GtagEvent.Gift, { reward: inviteReward, rankReward: reward })
        if (!inviteRewardTon && !inviteReward && !reward) {
            setSheetContent({
                title: t('modal.gift.none'),
                text: info?.prompt || t('modal.invite.more'),
                button: t('modal.invite.invite'),
                balance: '',
                type: SheetContentType.None,
                extra: undefined
            })
            setShowSheet(true);
            return;
        }

        if (reward) {
            setSheetContent({
                title: t('modal.invite.competition'),
                balance: reward.toFixed(2),
                button: t('modal.invite.get'),
                type: SheetContentType.InviteRank,
                text: '',
                extra: undefined
            })
        } else {
            setSheetContent({
                title: t('modal.invite.invite_people', { people: info?.inviteCount }),
                balance: inviteReward.toFixed(2),
                button: t('modal.invite.get'),
                type: SheetContentType.Invite,
                text: '',
                extra: info?.inviteRewardTon ? [{
                    icon: <Icon
                        name='ton_coin'
                        width='1.5rem'
                    />,
                    count: info?.inviteRewardTon
                }] : undefined
            })
        }
        setShowSheet(true)
    }, [t])

    return <>
        <Header
            isNew={true}
            inteval={SECOND_MILL * Number(data?.detector.speedRate || 1)}
            btcCount={btcCount}
            countPerInterval={data?.detector.realDetPower || 0}
            dynamicInterval={dynamicInterval}
            onStop={refresh}
            stopTime={stopTime}
        />
        <Center>
            <Content
                stopTime={stopTime}
                onStart={refresh}
                data={data}
                isStart={isStart}
                leftCycleCount={leftCycleCount}
            />
        </Center>
        <Space minHeight='1.875rem' />
        <Bottom>
            <Gift onClick={() => onGiftClick(rewardInfo)}>
                {showGiftDot ? <Dot /> : undefined}
                <Icon
                    name='home_gift'
                    width='2rem'
                />
            </Gift>
            <Channel />
        </Bottom>
        <Sheet
            upgrade={{
                icons: sheetIcons,
                text: sheetContent.text
            }}
            closable={true}
            title={<SheetTitle>{sheetContent.title}</SheetTitle>}
            type='modal'
            show={showSheet}
            onClose={() => setShowSheet(false)}
            confirm={{ key: 'confirm', label: sheetContent.button, onClick: onSheetConfirmClick }}
        />
        <Loading
            show={loading}
        />
    </>
}

Main

export default Home